package com.reus.transaction;

import com.reus.datasource.PoolDataSource;

import java.sql.Connection;
import java.sql.SQLException;

/**
 * description: 事务的简单实现，封装了数据库的事务功能
 * copyright: Copyright (c) 2018-2021
 * company: iSysCore Tech. Co., Ltd.
 *
 * @author liuxq@isyscore.com
 * @version 1.0
 * @date 2021-10-19 19:14:53
 */
public class SimpleTransaction implements Transaction {

    private Connection connection; // 数据库连接
    private PoolDataSource dataSource; // 数据源
    private Integer level = Connection.TRANSACTION_REPEATABLE_READ; // 事务隔离级别
    private Boolean autoCommmit = true; // 是否自动提交

    public SimpleTransaction(PoolDataSource dataSource) {
        this(dataSource, null, null);
    }

    public SimpleTransaction(PoolDataSource dataSource, Integer level, Boolean autoCommmit) {
        this.dataSource = dataSource;
        if (level != null) {
            this.level = level;
        }
        if (autoCommmit != null) {
            this.autoCommmit = autoCommmit;
        }
    }

    /**
     * 获取数据库连接，并设置该连接的事务隔离级别，是否自动提交
     */
    @Override
    public Connection getConnection() throws SQLException {
        if (connection != null) {
            return connection;
        }
        this.connection = dataSource.getConnection();

        this.connection.setAutoCommit(autoCommmit);

        this.connection.setTransactionIsolation(level);

        return this.connection;
    }

    @Override
    public void commit() throws SQLException {
        if (this.connection != null) {
            this.connection.commit();
        }
    }

    @Override
    public void rollback() throws SQLException {
        if (this.connection != null) {
            this.connection.rollback();
        }
    }

    /**
     * 关闭连接
     */
    @Override
    public void close() throws SQLException {
        /**如果该连接设置自动连接为false,则在关闭前进行事务回滚一下*/
        if (autoCommmit != null && !autoCommmit) {
            connection.rollback();
        }

        if (connection != null) {
            dataSource.removeConnection(connection);
        }

        this.connection = null;
    }
}
